﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;

namespace RockBus.DataContracts
{
    [DataContract(Namespace = StringConstants.RockBusNamespace)]
    public class SubscriberInfo : EvaluationElement<SubscriptionInfo, SubscriptionDetail>
    {
        private SubscriberInfo()
            : base()
        {
            this.Init();
        }

        public SubscriberInfo(string id,
            bool isStatic = false,
            IEnumerable<NamespaceInfo> namespaceInfos = null,
            IEnumerable<FilterInfo> filterInfos = null,
            IEnumerable<EndpointInfo> endpointInfos = null,
            IEnumerable<PipelineInfo> pipelineInfos = null,
            IEnumerable<SubscriptionInfo> infos = null,
            DateTime? modificationDateTimeUtc = null)
            : base(id, isStatic, namespaceInfos, filterInfos, endpointInfos, pipelineInfos, infos, modificationDateTimeUtc)
        {
            this.Init();
        }

        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            this.Init();
        }

        private void Init()
        {
            foreach (SubscriptionInfo sci in this.InfoDictionary.Values)
            {
                sci.SubscriberInfo = this;
            }
            if (null == this.PipelineInfoDictionary)
            {
                this.PipelineInfoDictionary = new CaseInsensitiveStringDictionary<PipelineInfo>();
            }
        }

        public void AddSubscriptionInfo(SubscriptionDetail detail, IEnumerable<string> filterIds)
        {
            var subscriptionInfo = new SubscriptionInfo(this, detail, filterIds);
            this.InfoDictionary.Add(subscriptionInfo.Id, subscriptionInfo);
        }

        public void AddSubscriptionInfo(SubscriptionDetail detail, params string[] filterIds)
        {
            this.AddSubscriptionInfo(detail, (IEnumerable<string>)filterIds);
        }

        public override void PurgeExpired(DateTime utcNow)
        {
            foreach (SubscriptionInfo sci in this.InfoDictionary.Values.ToArray())
            {
                if (sci.Detail.ExpiryDateTimeUtc < utcNow)
                {
                    this.InfoDictionary.Remove(sci.Detail.Id);
                }
            }
        }
    }
}